using System.Diagnostics;
using System.Text;
using Microsoft.Extensions.Logging;
using NLog;
using Vin.Extension.Exception.Interface;
using Vin.Extension.Framework.Options.Exception;
using Vin.Extension.NLog;
using Vin.Extension.Notify.QiyeWechat.Service;
using Vin.Tool.AspNetCore.Singleton;
using Vin.Tool.Core.NetCategory;

namespace Vin.Extension.Framework.Handlers.Exception;

public class QwExceptionNotifyHandler : IExceptionNotifyHandler
{
    private QwNotifyOption Option => VinApp.GetConfig<QwNotifyOption>();

    private QwSendMsgService QwSendMsgService => VinApp.GetRequiredServiceByHttpContext<QwSendMsgService>();
    
    private ILogger<QwExceptionNotifyHandler> Logger => VinApp.GetLogger<QwExceptionNotifyHandler>();

    public async Task NotifyAsync(System.Exception exception, int code, string? msg = null)
    {
        if (!Option.Enable || Option.Senders.Count <= 0) return;
        
        var id = Guid.NewGuid().ToString();
        // 获取堆栈信息
        var stackTrace = new StackTrace(true).ToString();
        var trace = stackTrace.Substring(0,
            stackTrace.Length > 300 ? 300 : stackTrace.Length);
        var sb = new StringBuilder();
        sb.Append($"运行出现异常：\n");
        sb.Append($"> 运行应用：<font color=\"warning\">{VinApp.WebHostEnvironment.ApplicationName}</font>\n");
        sb.Append($"> 运行环境：<font color=\"warning\">{VinApp.WebHostEnvironment.EnvironmentName}</font>\n");
        sb.Append($"> 日志标识：<font color=\"warning\">{id}</font>\n");

        if (VinApp.HaveHttpContext)
        {
            sb.Append($"> 请求地址：<font color=\"warning\">{VinApp.HttpContext.Request.Path}</font>\n");
            sb.Append($"> 请求ID：<font color=\"warning\">{VinApp.HttpContext.GetRequestId()}</font>\n");
        }

        sb.Append($"> 异常代码：<font color=\"warning\">{code}</font>\n");
        sb.Append($"> 异常信息：<font color=\"warning\">{msg}</font>\n");
        sb.Append($"> 异常堆栈：{trace}\n");
        sb.Append($"\n 详细内容请查看日志");
        
        // TODO：考虑保存到数据库
        Logger.Info(this.GetType().Name,$"日志标识：{id}，异常代码：{code}，异常信息：{msg}，异常堆栈：{stackTrace}");

        foreach (var s in Option.Senders)
        {
            await QwSendMsgService.SendMarkdownMessageAsync(s, sb.ToString(), Option.Receivers);
        }
    }
}